package com.tg.appcommon.imagecache;
import android.app.Activity;
import android.content.Context;
import android.graphics.Bitmap;
import android.os.AsyncTask;
import android.os.Environment;
import android.util.Log;
import android.util.LruCache;
import android.widget.Toast;


import com.module.appcommon.BuildConfig;

import java.io.File;
import java.io.IOException;

import static android.os.Environment.isExternalStorageRemovable;

public class ImageCache {
    private static  final  String TAG ="ImageCache";
    Context context;
    private DiskLruCache mDiskLruCache;
    private final Object mDiskCacheLock = new Object();
    private boolean mDiskCacheStarting = true;
    private LruCache<String, Bitmap> mMemoryCache;
    private static final long DISK_CACHE_SIZE = 1024 * 1024 * 50; // 50MB
    private static final String DISK_CACHE_SUBDIR = "thumbnails";


    public ImageCache(Context context) {
        // Initialize memory cache
        this.context=context;
        // Initialize disk cache on background thread
        File cacheDir = getDiskCacheDir(context, DISK_CACHE_SUBDIR);
        new InitDiskCacheTask().execute(cacheDir);
        final int maxMemory = (int) (Runtime.getRuntime().maxMemory() / 1024);

        // Use 1/8th of the available memory for this memory cache.
        final int cacheSize = maxMemory / 8;

        mMemoryCache = new LruCache<String, Bitmap>(cacheSize) {
            @Override
            protected int sizeOf(String key, Bitmap bitmap) {
                // The cache size will be measured in kilobytes rather than
                // number of items.
                return bitmap.getByteCount() / 1024;
            }
        };

    }
    class InitDiskCacheTask extends AsyncTask<File, Void, Void> {
        @Override
        protected Void doInBackground(File... params) {
            synchronized (mDiskCacheLock) {
                File cacheDir = params[0];
                mDiskLruCache = DiskLruCache.openCache(context,cacheDir, DISK_CACHE_SIZE);
                mDiskCacheStarting = false; // Finished initialization
                mDiskCacheLock.notifyAll(); // Wake any waiting threads
            }
            return null;
        }
    }


    public boolean isThisBitmapCached(String key)   {
        return getBitmapFromDiskCache(key,false) != null;
    }
    public void removeBitmapCache(String key)   {
        if (mMemoryCache!=null&&mMemoryCache.get(key)!=null){
            mMemoryCache.remove(key);
        }
         if (isThisBitmapCached(key)){
             if (mDiskLruCache !=null) {
                 mDiskLruCache.remove(key);
             }
         }
    }

    public void addBitmapToCache(String key, Bitmap bitmap)  {
        // Add to memory cache as before
        if (mMemoryCache!=null){
            if (BuildConfig.DEBUG) {
                Log.d(TAG, "mMemoryCache cache put");
            }
            mMemoryCache.put(key, bitmap);
        }
        // Also add to disk cache
        synchronized (mDiskCacheLock) {
            if (mDiskLruCache != null) {
                mDiskLruCache.put(key, bitmap);
            }
        }
    }


    private Bitmap getBitmapFromDiskCache(String key,boolean isMemoryCache) {
        if (mMemoryCache!=null&&mMemoryCache.get(key)!=null&& isMemoryCache){
            if (BuildConfig.DEBUG) {
                Log.d(TAG, "mMemoryCache cache get");
            }
            Bitmap memoryBitmap = mMemoryCache.get(key);
            if (memoryBitmap != null && !memoryBitmap.isRecycled()) {
                return memoryBitmap;
            } else {
                mMemoryCache.remove(key);
            }
        }
        synchronized (mDiskCacheLock) {
            // Wait while disk cache is started from background thread
            while (mDiskCacheStarting) {
                try {
                    mDiskCacheLock.wait();
                } catch (InterruptedException e) {
                    Toast.makeText(context,"getBitmapFromDiskCache  "+ e.getMessage(), Toast.LENGTH_SHORT).show();
                }
            }
            if (mDiskLruCache != null) {
                return mDiskLruCache.get(key);
            }
        }
        return null;
    }
    public Bitmap getBitmapFromDiskCache(String key){
        return  getBitmapFromDiskCache(key,true);
    }

    // Creates a unique subdirectory of the designated app cache directory. Tries to use external
// but if not mounted, falls back on internal storage.
    public static File getDiskCacheDir(Context context, String uniqueName) {
        // Check if media is mounted or storage is built-in, if so, try and use external cache dir
        // otherwise use internal cache dir
        String externalCacheDir = context.getExternalCacheDir() == null? "" : context.getExternalCacheDir().getPath();
        String cacheDir = context.getCacheDir() == null? "" : context.getCacheDir().getPath();
        final String cachePath = Environment.MEDIA_MOUNTED.equals(Environment.getExternalStorageState()) ||
                        !isExternalStorageRemovable() ? externalCacheDir : cacheDir;

        return new File(cachePath + File.separator + uniqueName);
    }
}